home *** CD-ROM | disk | FTP | other *** search
- /*
- * fm.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /*
- * F(ast)M(oments).C
- *
- * routines to extract, from the input image, values of the coefficients
- * for the Hatamian filter array and to evaluate various moments and
- * related quantities
- */
-
- #include "xfm.h"
-
- #define ZERO 0
- #define NOLOOP ZERO
-
- #undef DUMP_IMG
- #undef F_DEBUG
- #undef AP_DEBUG
- #define DEBUG
-
- /*
- * filter_recursion()
- * DESCRIPTION:
- * extract filter array from image
- * ARGUMENTS:
- * lx: leftmost x (int)
- * rx: rightmost x (int)
- * nr: number of rows (int)
- * nc: number of columns (int)
- * y: output array for filter (float **)
- * xdim: x size of moment matrix (int)
- * ydim: y size of moment matrix (int)
- * imgIn: image (Image *)
- * RETURN VALUE:
- * number of mode parameters
- */
-
- void
- filter_recursion (lx, rx, nr, nc, y, xdim, ydim, imgIn)
- int lx, rx;
- int nr, nc;
- float *y[];
- int xdim, ydim;
- Image *imgIn;
- {
- int p, q;
- int i, j;
- int imij;
- double hz1, hz2, hz3, hz4;
-
-
- printf ("\n...executing recursion to obtain Y - matrix...\n");
-
- printf ("\n...row:");
- for (i = 1; i < nr; i++) {
- if (i % 50 == 0)
- printf ("...%3d", i);
-
- hz1 = hz2 = hz3 = hz4 = 0.0;
- for (j = 0; j < nc; j++) {
- if ((imij = (int) getpixel (j, i, imgIn)) != 0)
- imij /= imij;
- //if( (imij = inq_index(i, j)) != 0 ) imij /= imij;
-
- hz4 += hz3;
- hz3 += hz2;
- hz2 += hz1;
- hz1 += (double) imij;
- }
-
- for (p = ydim - 1; p >= 1; p--) {
- for (q = 0; q < xdim; q++)
- *(y[q] + p) += *(y[q] + (p - 1));
- }
- *(y[0] + 0) += (float) hz1;
- *(y[1] + 0) += (float) hz2;
- *(y[2] + 0) += (float) hz3;
- *(y[3] + 0) += (float) hz4;
- }
-
- #ifdef F_DEBUG
- printf ("\n...filter output (Y-matrix):\n");
- for (p = 0; p < ydim; p++) {
- for (q = 0; q < xdim; q++) {
- printf (" y[%d][%d] = %f ", p, q, *(y[p] + q));
- printf ("\n");
- }
- }
- #endif
- }
-
-
- #if 0
- /*
- * AP code to evaluate moments, given filter output in 2d array Y
- *
- * implementation of M. Hatamian's code involving matrix
- * element operations in form of matrix multiplication:
- *
- * m = cm*y*cm'; CM': transposed CM, *: matrix mult.
- */
- void
- ap_eval_mom (y, m, mdim)
- float *y[], *m[];
- long mdim;
- {
- int i, j;
- float *y_out;
-
- long mmdd;
- long ap_dim;
- long ap_y, ap_cm, ap_m;
- long handle_1;
-
- mmdd = mdim * mdim;
-
- #ifdef AP_DEBUG
- printf ("\n...input data:\n");
- for (i = 0; i < (int) mdim; i++) {
- for (j = 0; j < mdim; j++) {
- printf (" %07.4f ", y[i][j]);
- if ((j + 1) % 4 == 0)
- printf ("\n");
- }
- printf ("\n");
- }
- #endif
-
- /*
- * allocate memory
- */
- if ((y_out = (float *) calloc (mmdd, sizeof (float))) == NULL)
- fail_alloc ("y", 1);
- /*
- * allocate AP memory
- */
- ap_dim = (long) ipaloc (1L);
- ap_y = (long) ipaloc (mmdd);
- ap_m = (long) ipaloc (mmdd);
- ap_cm = (long) ipaloc (mmdd);
-
- #ifdef AP_DEBUG
- apmdia ();
- #endif
-
- printf ("\n...transfer data to array processor\n");
- /*
- * load data onto AP
- */
- apputa ((long) y, ap_y, mmdd);
- apputa ((long) cm, ap_cm, mmdd);
- apputv ((float) mdim, ap_dim);
-
-
- #ifdef AP_DEBUG
- /*
- * check whether appropriate values have been transferred
- */
- printf ("\n...input matrix, as read back:\n");
- apgeta (ap_y, (long) y_out, mmdd);
- for (i = 0; i < (int) mmdd; i++) {
- printf ("%07.4f ", *(y_out + i));
- if ((i + 1) % 4 == 0)
- printf ("\n");
- }
- apputa ((long) y_out, ap_y, mmdd);
-
- #endif
-
- /*
- * instructions to execute the operations of interest
- */
- apmac (&handle_1);
- rmmul (ap_cm, ap_dim, ap_y, ap_dim, ap_y, ap_dim,
- ap_dim, ap_dim, ap_dim);
- rtrn2 (ap_cm, ap_dim, ap_dim);
- rmmul (ap_y, ap_dim, ap_cm, ap_dim, ap_m, ap_dim,
- ap_dim, ap_dim, ap_dim);
- apendm (handle_1, NOLOOP);
-
- /* pass handles to routines */
- apgo (handle_1);
- printf ("\n\n...ckeck DONE flag (do not wait if not set): ");
- printf (" %d\n", ipdtst ());
-
- /* output is now available and may be fetched */
- apgeta (ap_m, (long) m, mmdd);
- printf ("\n...moment output:\n");
- for (j = 0; j < (int) mdim; j++) {
- for (i = 0; i < (int) mdim; i++) {
- printf (" %07.4f", m[i][j]);
- if ((i + 1) % (int) mdim == 0)
- printf ("\n");
- }
- }
- free (y_out);
- }
-
- #endif
-
- /*
- * eval_mom()
- * DESCRIPTION:
- * evaluate moments, given filter output in 2d array Y
- * implementation of M. Hatamian's code involving matrix
- * element operations in form of matrix multiplication:
- * m = cm*y*cm'; CM': transposed CM, *: matrix mult.
- * ARGUMENTS:
- * y: input matrix (float **)
- * m: output matrix (float **)
- * mdim: number of rows, cols in matrices (int)
- * RETURN VALUE:
- * none
- */
-
- void
- eval_mom (y, m, mdim)
- float *y[], *m[];
- int mdim;
- {
- int i, j, k;
-
- #ifdef DEBUG
- printf ("\n...coefficient arrays\n");
- printf ("...cm:\n");
- for (j = 0; j < mdim; j++) {
- for (i = 0; i < mdim; i++) {
- printf (" %4.2f ", cm[j][i]);
- }
- printf ("\n");
- }
- printf ("...cmt:\n");
- for (j = 0; j < mdim; j++) {
- for (i = 0; i < mdim; i++) {
- printf (" %4.2f ", cmt[j][i]);
- }
- printf ("\n");
- }
- #endif
-
-
- /* matrix multiplications */
- for (j = 0; j < mdim; j++) {
- for (i = 0; i < mdim; i++) {
- *(m[j] + i) = (float) 0.0;
- for (k = 0; k < mdim; k++) {
- *(m[j] + i) += cm[j][k] * (*(y[k] + i));
- }
- }
- }
-
- for (j = 0; j < mdim; j++) {
- for (i = 0; i < mdim; i++) {
- *(y[j] + i) = (float) 0.0;
- for (k = 0; k < mdim; k++) {
- *(y[j] + i) += *(m[j] + k) * cmt[k][i];
- }
- }
- }
-
-
- for (j = 0; j < mdim; j++) {
- for (i = 0; i < mdim; i++) {
- *(m[j] + i) = *(y[j] + i);
- }
- }
- }
-
-
-
-
- /*
- * evaluate central moments
- */
- /*
- * central_moments()
- * DESCRIPTION:
- * evaluate central moments
- * ARGUMENTS:
- * m: input matrix (float **)
- * mu00: central moment (float *)
- * mu11: central moment (float *)
- * mu02: central moment (float *)
- * mu20: central moment (float *)
- * xc: centroid (float *)
- * yc: centroid (float *)
- * r_gyr: radius of gyration (float *)
- * dent: eccentricity (float *)
- * RETURN VALUE:
- * none
- */
-
- void
- central_moments (m, mu00, mu11, mu02, mu20, xc, yc, r_gyr, dent)
- float **m;
- float *mu00, *mu11, *mu02, *mu20;
- float *xc, *yc, *r_gyr, *dent;
- {
- float vmu00;
-
- /*
- * centroid
- */
- *xc = (*(m[1] + 0) / *(m[0] + 0));
- *yc = (*(m[0] + 1) / *(m[0] + 0));
- printf ("\ncentroid:\n");
- printf ("...x_bar = %f y_bar = %f\n", *xc, *yc);
-
- /*
- * central moments and radius of gyration
- */
- printf ("...m00 = %f\n", *(m[0] + 0));
- vmu00 = *mu00 = *(m[0] + 0);
- *mu11 = (*(m[1] + 1) - vmu00 * (*(m[1] + 0) / vmu00) * (*(m[0] + 1) / vmu00));
- *mu20 = (*(m[2] + 0) - vmu00 * (*(m[1] + 0) / vmu00) * (*(m[1] + 0) / vmu00));
- *mu02 = (*(m[0] + 2) - vmu00 * (*(m[0] + 1) / vmu00) * (*(m[0] + 1) / vmu00));
-
- *r_gyr = (float) sqrt ((*mu20 + *mu02) / (vmu00));
- *dent = ((*mu02 - *mu20) / (*mu20 + *mu02));
- }
-